﻿using DotNetty.Transport.Channels;
using InkjetControl.codec;
using InkjetControl.events;
using InkjetControl.NLog;
using InkjetControl.view;
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace InkjetControl.model
{
    public class DeviceListModel : ViewModelBase
    {
        public DeviceListModel()
        {
            DeviceItems = CreateData();
            IsAllSelected = false;
            StartPrintCommand = new AnotherCommandImplementation(_ =>
            {
                Log.Logger.Info("PrintCommand");
                MsgDialogInfoModel dialogInfoModel = new MsgDialogInfoModel()
                {
                    Msg = "是否启动所有设备喷印，按确定按钮将启动开始喷印，否则请按取消按钮",
                    IsShowCancelBtn = Visibility.Visible,
                    IsShowCloseBtn = Visibility.Hidden,
                    IsShowConfirmBtn = Visibility.Visible
                };
                dialogInfoModel.OnDialogConfirmBtnHandler += StartPrint_OnDialogConfirmBtnHandler;
                MsgDialog msgDialog = new MsgDialog()
                {
                    DataContext = dialogInfoModel
                };
                _ = DialogHost.Show(msgDialog);
                
            });

            StopPrintCommand = new AnotherCommandImplementation(_ =>
            {
                Log.Logger.Info("StopPrintCommand");
                MsgDialogInfoModel dialogInfoModel = new MsgDialogInfoModel()
                {
                    Msg = "是否需要所有设备停止喷印，点确认即将所有设备停止喷印操作，否则请按取消按钮",
                    IsShowCancelBtn = Visibility.Visible,
                    IsShowCloseBtn = Visibility.Hidden,
                    IsShowConfirmBtn = Visibility.Visible
                };
                dialogInfoModel.OnDialogConfirmBtnHandler += StopPrint_OnDialogConfirmBtnHandler;
                MsgDialog msgDialog = new MsgDialog()
                {
                    DataContext = dialogInfoModel
                };
                _ = DialogHost.Show(msgDialog);
                
            });

            StartSuppyInkCommand = new AnotherCommandImplementation(_ =>
            {
                Log.Logger.Info("SuppyInkCommand");
                MsgDialogInfoModel dialogInfoModel = new MsgDialogInfoModel()
                {
                    Msg = "是否启动所有设备供墨，确认开始供墨，取消不执行",
                    IsShowCancelBtn = Visibility.Visible,
                    IsShowCloseBtn = Visibility.Hidden,
                    IsShowConfirmBtn = Visibility.Visible
                };
                dialogInfoModel.OnDialogConfirmBtnHandler += StartSuppyInk_OnDialogConfirmBtnHandler;
                MsgDialog msgDialog = new MsgDialog()
                {
                    DataContext = dialogInfoModel
                };
                _ = DialogHost.Show(msgDialog);
                
            });

            StopSuppyInkCommand = new AnotherCommandImplementation(_ =>
            {
                Log.Logger.Info("SuppyInkCommand");
                MsgDialogInfoModel dialogInfoModel = new MsgDialogInfoModel()
                {
                    Msg = "是否将所有设备停止供墨操作，如确认执行停止供墨操作请按确定按钮，否则请按取消按钮",
                    IsShowCancelBtn = Visibility.Visible,
                    IsShowCloseBtn = Visibility.Hidden,
                    IsShowConfirmBtn = Visibility.Visible
                };
                dialogInfoModel.OnDialogConfirmBtnHandler += StopSuppyInk_OnDialogConfirmBtnHandler;
                MsgDialog msgDialog = new MsgDialog()
                {
                    DataContext = dialogInfoModel
                };
                _ = DialogHost.Show(msgDialog);
               
            });

            foreach (DeviceItemModel model in DeviceItems)
            {
                model.PropertyChanged += (sender, args) =>
                {
                    if (args.PropertyName == nameof(DeviceItemModel.IsSelected))
                    {
                        OnPropertyChanged(nameof(IsAllSelected));
                    }
                };
            }

            EventBus.OnLoginHandler += EventBus_OnLoginHandler;
            EventBus.OnLogoutHandler += EventBus_OnLogoutHandler;
        }

        private void StartPrint_OnDialogConfirmBtnHandler()
        {
            foreach (DeviceItemModel model in DeviceItems)
            {
                if (model.IsSelected)
                {
                    if (model.StatusModel.EquipmentState >= EquipmentState.DONE_INK && model.StatusModel.EquipmentState < EquipmentState.PRINTING)
                    {
                        Message msg = new Message
                        {
                            MachineCode = model.DeviceId,
                            MachineLabel = model.DeviceName,
                            MessageType = MessageType.REQUEST,
                        };

                        if (!model.IsPrinting)
                        {
                            msg.Body = Message.GenerateMsgBody(NetCmd.START_PRINT);
                            EventBus.SendMsgHandler(model.DeviceId, msg);
                        }

                    }
                }

            }
        }
        private void StopPrint_OnDialogConfirmBtnHandler()
        {
            foreach (DeviceItemModel model in DeviceItems)
            {
                if (model.IsSelected)
                {
                    if (model.StatusModel.EquipmentState == EquipmentState.PRINTING)
                    {
                        Message msg = new Message
                        {
                            MachineCode = model.DeviceId,
                            MachineLabel = model.DeviceName,
                            MessageType = MessageType.REQUEST,
                        };

                        if (model.IsPrinting)
                        {
                            msg.Body = Message.GenerateMsgBody(NetCmd.STOP_PRINT);
                            EventBus.SendMsgHandler(model.DeviceId, msg);
                        }

                    }
                }
            }
        } 
        private void StartSuppyInk_OnDialogConfirmBtnHandler()
        {
            foreach (DeviceItemModel model in DeviceItems)
            {
                if (model.IsSelected)
                {
                    Message msg = new Message
                    {
                        MachineCode = model.DeviceId,
                        MessageType = MessageType.REQUEST,
                    };
                    if (model.StatusModel.EquipmentState == EquipmentState.STOPPED)
                    {

                        msg.Body = Message.GenerateMsgBody(NetCmd.START_SUPPLY_INK);
                    }
                    EventBus.SendMsgHandler(model.DeviceId, msg);
                }
            }
        }
        private void StopSuppyInk_OnDialogConfirmBtnHandler()
        {
            foreach (DeviceItemModel model in DeviceItems)
            {
                if (model.IsSelected)
                {
                    Message msg = new Message
                    {
                        MachineCode = model.DeviceId,
                        MessageType = MessageType.REQUEST,
                    };
                    if (model.StatusModel.EquipmentState != EquipmentState.STOPPED)
                    {
                        bool isQuickyStop = false;
                        msg.Body = Message.GenerateMsgBody(NetCmd.STOP_SUPPLY_INK, ref isQuickyStop);
                    }
                    EventBus.SendMsgHandler(model.DeviceId, msg);
                }
            }
        }

        private void EventBus_OnLogoutHandler(string machineCode)
        {
            _ = ThreadPool.QueueUserWorkItem(delegate
            {
                SynchronizationContext.SetSynchronizationContext(new
                     DispatcherSynchronizationContext(Application.Current.Dispatcher));
                SynchronizationContext.Current.Post(pl =>
                {
                    foreach (DeviceItemModel itemModel in DeviceItems)
                    {
                        if (itemModel.DeviceId == machineCode)
                        {
                            itemModel.Destory();
                            _ = DeviceItems.Remove(itemModel);
                            break;
                        }
                    }
                    IsEnableMoreDevice = DeviceItems.Count > 1;
                }, null);

            });
            
        }

        private void EventBus_OnLoginHandler(string machineCode, string deviceName, IChannel channel)
        {
            _ = ThreadPool.QueueUserWorkItem(delegate
            {
                SynchronizationContext.SetSynchronizationContext(new
                     DispatcherSynchronizationContext(Application.Current.Dispatcher));
                SynchronizationContext.Current.Post(pl =>
                {
                    DeviceItems.Add(new DeviceItemModel(machineCode, deviceName));
                    Message msg = new Message
                    {
                        MachineCode = machineCode,
                        MachineLabel = deviceName,
                        MessageType = MessageType.REQUEST,
                        Body = Message.GenerateMsgBody(NetCmd.GET_PRINT_PARAMS)
                    };
                    EventBus.SendMsgHandler(machineCode, msg);
                    IsEnableMoreDevice = DeviceItems.Count > 1;
                }, null);

            });
          
        }

        public bool? IsAllSelected
        {
            get
            {
                var selected = DeviceItems.Select(item => item.IsSelected).Distinct().ToList();
                return selected.Count == 1 ? selected.Single() : (bool?)null;
            }
            set
            {
                if (value.HasValue)
                {
                    SelectAll(value.Value, DeviceItems);
                    OnPropertyChanged();
                }
            }
        }

        private static void SelectAll(bool select, IEnumerable<DeviceItemModel> models)
        {
            foreach (DeviceItemModel model in models)
            {
                model.IsSelected = select;
            }
        }

        private static ObservableCollection<DeviceItemModel> CreateData()
        {
            return new ObservableCollection<DeviceItemModel>();
        }


        private bool _isEnableMoreDevice;

        public ObservableCollection<DeviceItemModel> DeviceItems { get; }
        public ICommand StartPrintCommand { get; }
        public ICommand StopPrintCommand { get; }
        public ICommand StartSuppyInkCommand { get; }
        public ICommand StopSuppyInkCommand { get; }
        public bool IsEnableMoreDevice 
        {
            get => _isEnableMoreDevice; 
            set => SetProperty(ref _isEnableMoreDevice , value); }
    }
}
